# lmLatexWriter.R
#
# Function to write out an R lm object
# as a latex table.
#

lmLatexWriter <- function(listOfLms,
                            robustSEs=NULL,
                            toFile=TRUE,
                            rounder="%7.2f",
                            vars=NULL,
                            varlabs=NULL,
                            statsLs=list(adj.r.squared="Adjusted R-Squared",
                                        sigma="Std. Error of Regression"),
                            outfile="lmTable.tex") {
    
    if (toFile) sink(file=outfile,type="output")
    
    # Change lm objects to summary(lm) objects
    for (o in names(listOfLms)) {
        if (any(class(listOfLms[[o]])=='list')) next     # User-defined without summary method
        listOfLms[[o]] <- summary(listOfLms[[o]])
    }    

    # Header and variable identification
    cat(sprintf("%-29s",""))
    for (n in names(listOfLms)) {
        cat(sprintf("&  %-7s  ",n))
    }
    cat("\\\\\n")
    cat("\\cline{2-",length(listOfLms)+1,"} \\\\\n",sep="")   # Line below model names
    cat("\n")

    # Create list of variables if not provided as argument
    if (is.null(vars)) {
        for (o in listOfLms) {
            vars <- union(vars,rownames(o$coefficients))
        }
    }

    # If label names are not specified, use actual variable names
    if (is.null(varlabs)) {
        varlabs <- list()
        for (v in vars) varlabs[[v]] <- as.character(v)
    } else {
        if ("(Intercept)"%in%names(varlabs)==F) {
            varlabs[["(Intercept)"]] <- "Intercept"
        }
    }
    
    # Create variable rows
    for (v in vars) {
        varname <- varlabs[[v]]
        if (is.null(varname)) varname <- v
        cat(sprintf("%-29s",varname))

        for (o in names(listOfLms)) {
            # Identify coefficient vector, from the summary
            # of the lm object `o'.
            coefs <- listOfLms[[o]]$coefficients[,'Estimate']
            names(coefs) <- rownames(listOfLms[[o]]$coefficients)
            if(v %in% names(coefs)) {
                cat(sprintf(paste("&  ",rounder,"  ",sep=''), coefs[v]))
            }
            else {
                cat("&           ")
            }
        }
        cat("\\\\\n")
        cat(sprintf("%-29s",""))
        for (o in names(listOfLms)) {
            # Identify the standard error vector,
            # either from lm object or from the named element of
            # `robustSEs' if provided.
            if (o %in% names(robustSEs)) {
                ses <- robustSEs[[o]]
            } else {
                ses <- listOfLms[[o]]$coefficients[,'Std. Error']
                names(ses) <- rownames(listOfLms[[o]]$coefficients)
            }
            if(v %in% names(ses)) {
                cat(sprintf(paste("& (",rounder,") ",sep=''), ses[v]))
            }
            else {
                cat("&           ")
            }
        }
        cat("\\\\\n")
    }

    cat("\\\\\n")
    # Print number of observations
    cat(sprintf("%-29s","N"))
    for (o in listOfLms) {
        if ( 'nobs'%in%names(o) ) {      
            cat( sprintf("& %7s ",o$nobs) )
            next
        }
        if ( 'df'%in%names(o) ) {
            cat( sprintf("& %7s ",(o$df[1]+o$df[2])) )
            next
        } else { cat("& %7s ","-") }
    }    
    cat("\\\\\n")
    
    # --------------------------
    # Print Stats in statsLs
    # --------------------------
    for (st in names(statsLs)) {
        cat(sprintf("%-29s",statsLs[[st]]))
        for (o in listOfLms) {
            localstat <- o[[st]]
            if (is.null(localstat)) {
                cat(sprintf("&  %7s  "," "))
            } else {
                cat(sprintf(paste("&  ",rounder,"  ",sep=''),o[[st]]))
            }
        }
        cat("\\\\\n")
    }
    
    if (toFile) sink()
}
